﻿using System;
using System.Web;
using System.IO.Compression;
using System.IO;
using CostaRicaPureTravelUtils.CacheHandler.Configuration;
using CostaRicaPureTravelUtils.CacheHandler.ConfigurationUtils;

namespace CostaRicaPureTravelUtils.CacheHandler
{
    /// <summary>
    /// Handler for sending files to the client
    /// </summary>
    [Serializable] 
  public class CachingHandler : IHttpHandler
    {
        public bool IsReusable
        {
            get { return true; }
        }

        public void ProcessRequest(HttpContext context)
        {
            string file = context.Server.MapPath(context.Request.FilePath.Replace(".ashx", ""));
            string filename = file.Substring(file.LastIndexOf('\\') + 1);
            string extension = file.Substring(file.LastIndexOf('.') + 1);

            CachingSection config = (CachingSection)context.GetSection("CachingHandler/Caching");
            if (config != null)
            {
                CompressFile(context, context.Response.Filter);
                context.Response.Cache.SetExpires(DateTime.Now.Add(config.CachingTimeSpan));
                context.Response.Cache.SetCacheability(HttpCacheability.Public);
                context.Response.Cache.SetValidUntilExpires(true);
                //context.Response.Cache.SetLastModified(DateTime.Now.AddDays(config.CachingTimeSpan.Days));
                context.Response.Cache.SetLastModifiedFromFileDependencies();
                context.Response.Cache.SetETagFromFileDependencies();
                context.Response.Cache.SetProxyMaxAge(config.CachingTimeSpan);
                context.Response.Cache.SetVaryByCustom("Accept-Charset");
                context.Response.Cache.SetAllowResponseInBrowserHistory(true);
                FileExtension fileExtension = config.FileExtensions[extension];
                if (fileExtension != null)
                {
                    context.Response.ContentType = fileExtension.ContentType;
                }
            }
            context.Response.AddHeader("content-disposition", "inline; filename=" + filename);
            context.Response.AppendHeader("Vary", "Content-Encoding");
            context.Response.AddHeader("Vary", "Accept-Encoding");
            try
            {
                context.Response.WriteFile(file);
            }
            catch (Exception ex) 
            {
                //Exception
            }
        }

        private void CompressFile(HttpContext context, Stream file)
        {
            string acceptEncoding = context.Request.Headers["Accept-Encoding"];
            Stream compressFile = null;
            if (acceptEncoding.Contains("gzip"))
            { // gzip
                context.Response.Filter = new GZipStream(file, CompressionMode.Compress);
                context.Response.AppendHeader("Content-Encoding", "gzip");
            }
            else if (acceptEncoding.Contains("deflate"))
            { // defalte
                context.Response.Filter = new DeflateStream(file, CompressionMode.Compress);
                context.Response.AppendHeader("Content-Encoding", "deflate");
            }
            if (compressFile != null)
            {
                context.Response.Cache.VaryByHeaders["Accept-encoding"] = true;
            }            
        }
    }
}